package com.easygem.system.service.impl;

import com.easygem.common.enums.system.UserStatusEnum;
import com.easygem.common.enums.system.UserTypeEnum;
import com.easygem.common.error.SystemCodeEnum;
import com.easygem.common.error.SystemException;
import com.easygem.common.model.system.*;
import com.easygem.common.response.ActiveUser;
import com.easygem.common.utils.DepUtils;
import com.easygem.common.utils.MenuTreeBuilder;
import com.easygem.common.vo.system.*;
import com.easygem.system.converter.MenuConverter;
import com.easygem.system.jwt.JWTToken;
import com.easygem.system.jwt.JWTUtils;
import com.easygem.system.mapper.*;
import com.easygem.system.service.UserService;
import com.easygem.system.util.MD5Utils;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.sql.Timestamp;
import java.util.*;

/**
 * @Author 文晓平
 * @Date 2024/12/7 15:44
 * @Version 1.0
 **/
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private UserRoleMapper userRoleMapper;

    @Autowired
    private RoleMapper roleMapper;


    @Autowired
    private RoleMenuMapper roleMenuMapper;

    @Autowired
    private MenuMapper menuMapper;

    @Autowired
    private DeptClientMapper departmentMapper;


    /**
     * 查询用户
     *
     * @param name 用户名
     * @return
     */
    @Override
    public User findUserByName(String name) {
        User t = new User();
        t.setUserName(name);
        return userMapper.selectOne(t);
    }

    /**
     * 查询用户
     *
     * @param name 用户名
     * @return
     */
    @Override
    public User findUserByName(String name, String accountName) {
        User t = new User();
        t.setUserName(name);
        t.setAccountName(accountName);
        return userMapper.selectOne(t);
    }

    /**
     * 查询用户角色
     *
     * @param id 用户ID
     * @return
     */
    @Override
    public List<Role> findRolesById(Long id) throws SystemException {
        User dbUser = userMapper.selectByPrimaryKey(id);
        if (dbUser == null) {
            throw new SystemException(SystemCodeEnum.PARAMETER_ERROR, "该用户不存在");
        }
        List<Role> roles = new ArrayList<>();
        EmployeeRole t = new EmployeeRole();
        t.setUserId(dbUser.getUserId());
        List<EmployeeRole> employeeRoleList = userRoleMapper.select(t);
        List<Long> rids = new ArrayList<>();
        if (!CollectionUtils.isEmpty(employeeRoleList)) {
            for (EmployeeRole employeeRole : employeeRoleList) {
                rids.add(employeeRole.getRoleId());
            }
            if (!CollectionUtils.isEmpty(rids)) {
                for (Long rid : rids) {
                    Role role = roleMapper.selectByPrimaryKey(rid);
                    if (role != null) {
                        roles.add(role);
                    }
                }
            }
        }
        return roles;
    }

    /**
     * 查询权限
     *
     * @param roles 用户的角色
     * @return
     */
    @Override
    public List<Menu> findMenuByRoles(List<Role> roles) {
        List<Menu> menus = new ArrayList<>();
        if (!CollectionUtils.isEmpty(roles)) {
            Set<Long> menuIds = new HashSet<>();//存放用户的菜单id
            List<RoleMenu> roleMenus;
            for (Role role : roles) {
                //根据角色ID查询权限ID
                Example o = new Example(RoleMenu.class);
                o.createCriteria().andEqualTo("roleId", role.getRoleId());
                roleMenus = roleMenuMapper.selectByExample(o);
                if (!CollectionUtils.isEmpty(roleMenus)) {
                    for (RoleMenu roleMenu : roleMenus) {
                        menuIds.add(roleMenu.getMenuId());
                    }
                }
            }
            if (!CollectionUtils.isEmpty(menuIds)) {
                for (Long menuId : menuIds) {
                    //该用户所有的菜单
                    Menu menu = menuMapper.selectByPrimaryKey(menuId);
                    if (menu != null) {
                        menus.add(menu);
                    }
                }
            }
        }
        return menus;
    }

    /**
     * 获取菜单
     *
     * @return
     */
    @Override
    public List<MenuNodeVO> findMenu() {
        List<Menu> menus = null;
        List<MenuNodeVO> menuNodeVOS = new ArrayList<>();
        ActiveUser activeUser = (ActiveUser) SecurityUtils.getSubject().getPrincipal();
//        if(activeUser.getUser().getType()== UserTypeEnum.SYSTEM_ADMIN.getTypeCode()){
//            //超级管理员
//            menus=menuMapper.selectAll();
//        }else if(activeUser.getUser().getType()== UserTypeEnum.SYSTEM_USER.getTypeCode()){
        //普通系统用户
        menus = activeUser.getMenus();
//       }
        if (!CollectionUtils.isEmpty(menus)) {
            menuNodeVOS = MenuConverter.converterToMenuNodeVO(menus);
        }

        //构建树形菜单
        return MenuTreeBuilder.build(menuNodeVOS);
    }

    /**
     * 用户列表
     *
     * @param userVO
     * @return
     */
    @Override
    public PageVO<User> findUserList(Integer pageNum, Integer pageSize, UserVO userVO) {
        PageHelper.startPage(pageNum, pageSize);
        //已经拥有的
//        PageHelper.startPage(pageNum,pageSize);
//        Example o = new Example(User.class);
//        String username = userVO.getUsername();
//        String nickname = userVO.getNickname();
//        Long departmentId = userVO.getDepartmentId();
//        Integer sex = userVO.getSex();
//        String email = userVO.getEmail();
//        Example.Criteria criteria = o.createCriteria();
//        if(username!=null&&!"".equals(username)){
//            criteria.andLike("username","%"+username+"%");
//        }
//        if(nickname!=null&&!"".equals(nickname)){
//            criteria.andLike("nickname","%"+nickname+"%");
//        }
//        if(email!=null&&!"".equals(email)){
//            criteria.andLike("email","%"+email+"%");
//        }
//        if(sex!=null){
//            criteria.andEqualTo("sex",sex);
//        }
//        if(departmentId!=null){
//            criteria.andEqualTo("departmentId",departmentId);
//        }
//
//        criteria.andNotEqualTo("type",0);
//        List<User> userList = userMapper.selectByExample(o);
//        List<UserVO> userVOS = userConverter.converterToUserVOList(userList);
//        PageInfo<User> info=new PageInfo<>(userList);
//        return new PageVO<>(info.getTotal(),userVOS);

        User user = new User();
        BeanUtils.copyProperties(userVO, user);
        user.setAccountName(userVO.getAccountName());
        user.setStatus(userVO.getStatus());
        user.setUserName(userVO.getUserName());
        user.setPhone(userVO.getPhone());
        user.setNickName(userVO.getNickName());
        //获得登录用户所在部门及以下部门编号
        ActiveUser activeUser = (ActiveUser) SecurityUtils.getSubject().getPrincipal();
        //得到所有部门列表
        List<DeptClient> deptClients = departmentMapper.selectAll();
//        List<Long> ids = DepUtils.getDepartmentAndChildrenIds(depts, activeUser.getUser().getDeptId());
//        user.setIds(ids);
        List<User> userList = userMapper.selectUserList(user);

        PageInfo<User> info = new PageInfo<>(userList);
        return new PageVO<>(info.getTotal(), userList);
    }

    /**
     * 根据部门编号查询用户列表
     *
     * @param deptId 部门编号
     * @return
     */
    @Override
    public List<UserVO> findUserListByDept(Long deptId) {
        return userMapper.findUserListByDept(deptId);
    }

    /**
     * 删除用户
     *
     * @param id 用户ID
     */
    @Transactional
    @Override
    public void deleteById(Long id) throws SystemException {
        User user = userMapper.selectByPrimaryKey(id);
        ActiveUser activeUser = (ActiveUser) SecurityUtils.getSubject().getPrincipal();

        if (user == null) {
            throw new SystemException(SystemCodeEnum.PARAMETER_ERROR, "要下线的用户不存在");
        }

//        if(user.getUserId().equals(activeUser.getUser().getUserId())){
//            throw new SystemException(SystemCodeEnum.PARAMETER_ERROR,"不能删除当前登入用户");
//        }

        userMapper.deleteByPrimaryKey(id);
        //删除对应[用户-角色]记录
        Example o = new Example(EmployeeRole.class);
        o.createCriteria().andEqualTo("userId", id);
        userRoleMapper.deleteByExample(o);
    }

    /**
     * 更新用户禁用状态
     *
     * @param id
     * @param status
     */
    @Override
    public void updateStatus(Long id, Boolean status) throws SystemException {
        User dbUser = userMapper.selectByPrimaryKey(id);
        if (dbUser == null) {
            throw new SystemException(SystemCodeEnum.PARAMETER_ERROR, "要更新状态的用户不存在");
        }
        ActiveUser activeUser = (ActiveUser) SecurityUtils.getSubject().getPrincipal();
//        if(dbUser.getUserId().equals(activeUser.getUser().getUserId())){
//            throw new SystemException(SystemCodeEnum.PARAMETER_ERROR,"无法改变当前用户状态");
//        }else {
        User t = new User();
        t.setUserId(id);
        t.setStatus(status ? UserStatusEnum.DISABLE.getStatusCode() :
                UserStatusEnum.AVAILABLE.getStatusCode());
        userMapper.updateByPrimaryKeySelective(t);
//        }
    }

    /**
     * 添加用户
     *
     * @param userVO
     */
    @Transactional
    @Override
    public void add(UserVO userVO) throws SystemException {
        @NotBlank(message = "用户名不能为空") String username = userVO.getUserName();
        @NotNull(message = "部门id不能为空") Long departmentId = userVO.getDeptId();
        Example o = new Example(User.class);
        o.createCriteria().andEqualTo("userName", username);
        int i = userMapper.selectCountByExample(o);
        if (i != 0) {
            throw new SystemException(SystemCodeEnum.PARAMETER_ERROR, "该用户名已被占用");
        }
        DeptClient department = departmentMapper.selectByPrimaryKey(departmentId);
        if (department == null) {
            throw new SystemException(SystemCodeEnum.PARAMETER_ERROR, "该部门不存在");
        }
        User user = new User();
        BeanUtils.copyProperties(userVO, user);
        String salt = UUID.randomUUID().toString().substring(0, 32);
        user.setPassword(MD5Utils.md5Encryption(user.getPassword(), salt));
        user.setEditTime(new Timestamp(System.currentTimeMillis()));
        user.setCreateTime(new Timestamp(System.currentTimeMillis()));
        //获得到登录后的用户信息，通用方式
        ActiveUser activeUser = (ActiveUser) SecurityUtils.getSubject().getPrincipal();
//        user.setAccountName(activeUser.getUser().getAccountName());
        user.setSalt(salt);
        user.setType(UserTypeEnum.SYSTEM_USER.getTypeCode());//添加的用户默认是普通用户
        user.setStatus(UserStatusEnum.AVAILABLE.getStatusCode());//添加的用户默认启用
        //user.setAvatar("http://badidol.com/uploads/images/avatars/201910/24/18_1571921832_HG9E55x9NY.jpg");
        userMapper.insert(user);
    }

    /**
     * 更新
     *
     * @param id
     * @param userVO
     */
    @Transactional
    @Override
    public void update(Long id, UserEditVO userVO) throws SystemException {
        User dbUser = userMapper.selectByPrimaryKey(id);
        @NotBlank(message = "用户名不能为空") String username = userVO.getUserName();
        @NotNull(message = "部门不能为空") Long departmentId = userVO.getDeptId();
        if (dbUser == null) {
            throw new SystemException(SystemCodeEnum.PARAMETER_ERROR, "要删除的用户不存在");
        }
        DeptClient department = departmentMapper.selectByPrimaryKey(departmentId);
        if (department == null) {
            throw new SystemException(SystemCodeEnum.PARAMETER_ERROR, "该部门不存在");
        }
        Example o = new Example(User.class);
        o.createCriteria().andEqualTo("username", username);
        List<User> users = userMapper.selectByExample(o);
        if (!CollectionUtils.isEmpty(users)) {
            if (!users.get(0).getUserId().equals(id)) {
                throw new SystemException(SystemCodeEnum.PARAMETER_ERROR, "该用户名已被占用");
            }
        }
        User user = new User();
        BeanUtils.copyProperties(userVO, user);
        user.setEditTime(new Timestamp(System.currentTimeMillis()));
        user.setUserId(dbUser.getUserId());
        user.setDeptId(userVO.getDeptId());
        userMapper.updateByPrimaryKeySelective(user);
    }

    /**
     * 编辑
     *
     * @param id
     * @return
     */
    @Transactional
    @Override
    public UserEditVO edit(Long id) throws SystemException {
        User user = userMapper.selectByPrimaryKey(id);
        if (user == null) {
            throw new SystemException(SystemCodeEnum.PARAMETER_ERROR, "要编辑的用户不存在");
        }
        UserEditVO userEditVO = new UserEditVO();
        BeanUtils.copyProperties(user, userEditVO);
        DeptClient department = departmentMapper.selectByPrimaryKey(user.getDeptId());
        if (department != null) {
            userEditVO.setDeptId(department.getDeptId());
        }
        return userEditVO;
    }

    /**
     * 用户拥有的角色ID
     *
     * @param id 用户id
     * @return
     */
    @Transactional
    @Override
    public List<Long> roles(Long id) throws SystemException {
        User user = userMapper.selectByPrimaryKey(id);
        if (user == null) {
            throw new SystemException(SystemCodeEnum.PARAMETER_ERROR, "该用户不存在");
        }
        Example o = new Example(EmployeeRole.class);
        o.createCriteria().andEqualTo("userId", user.getUserId());
        List<EmployeeRole> employeeRoleList = userRoleMapper.selectByExample(o);
        List<Long> roleIds = new ArrayList<>();
        if (!CollectionUtils.isEmpty(employeeRoleList)) {
            for (EmployeeRole employeeRole : employeeRoleList) {
                Role role = roleMapper.selectByPrimaryKey(employeeRole.getRoleId());
                if (role != null) {
                    roleIds.add(role.getRoleId());
                }
            }
        }
        return roleIds;
    }

    /**
     * 分配角色
     *
     * @param id   用户id
     * @param rids 角色数组
     */
    @Override
    @Transactional
    public void assignRoles(Long id, Long[] rids) throws SystemException {
        //删除之前用户的所有角色
        User user = userMapper.selectByPrimaryKey(id);
        if (user == null) {
            throw new SystemException(SystemCodeEnum.PARAMETER_ERROR, "用户不存在");
        }
        //删除之前分配的
        Example o = new Example(EmployeeRole.class);
        o.createCriteria().andEqualTo("userId", user.getUserId());
        userRoleMapper.deleteByExample(o);
        //增加现在分配的
        if (rids.length > 0) {
            for (Long rid : rids) {
                Role role = roleMapper.selectByPrimaryKey(rid);
                if (role == null) {
                    throw new SystemException(SystemCodeEnum.PARAMETER_ERROR, "roleId=" + rid + ",该角色不存在");
                }
                //判断角色状态
                if (role.getStatus() == 0) {
                    throw new SystemException(SystemCodeEnum.PARAMETER_ERROR, "roleName=" + role.getRoleName() + ",该角色已禁用");
                }
                EmployeeRole employeeRole = new EmployeeRole();
                employeeRole.setUserId(id);
                employeeRole.setRoleId(rid);
                userRoleMapper.insert(employeeRole);
            }
        }
    }

    @Override
    public List<User> findAll() {
        User user = new User();
//        //获得登录用户所在部门及以下部门编号
//        ActiveUser activeUser = (ActiveUser) SecurityUtils.getSubject().getPrincipal();
//        //得到所有部门列表
//        List<Dept> depts = departmentMapper.selectAll();
//        List<Long> ids = DepUtils.getDepartmentAndChildrenIds(depts, activeUser.getUser().getDeptId());
//        user.setIds(ids);
        List<User> userList = userMapper.selectUserList(user);

        //return userMapper.selectAll();
        return userList;
    }

    /**
     * 用户登入
     *
     * @param username
     * @param password
     * @return
     */
    @Override
    public String login(String username, String password, String accountName) throws SystemException {
        String token;
        //1.先查询用户信息
        User user = findUserByName(username, accountName);
        if (user != null) {
            //密码盐
            String salt = user.getSalt();
            //秘钥为盐
            String target = MD5Utils.md5Encryption(password, salt);
            //根据用户名和密码盐 生成Token
            token = JWTUtils.sign(username, target);
            JWTToken jwtToken = new JWTToken(token);
            try {
                //去登陆
                SecurityUtils.getSubject().login(jwtToken);
                /**
                 * 1.登录后需要认证：UserRealm。doGetAuthenticationInfo()
                 */
            } catch (AuthenticationException e) {
                throw new SystemException(SystemCodeEnum.PARAMETER_ERROR, e.getMessage());
            }
        } else {
            throw new SystemException(SystemCodeEnum.PARAMETER_ERROR, "用户不存在");
        }
        return token;
    }

    /**
     * 用户详情
     *
     * @return
     */
    @Override
    public UserInfoVO info() throws SystemException {
        ActiveUser activeUser = (ActiveUser) SecurityUtils.getSubject().getPrincipal();
        UserInfoVO userInfoVO = new UserInfoVO();
//        userInfoVO.setAvatar(activeUser.getUser().getAvatar());
//        userInfoVO.setUserName(activeUser.getUser().getUserName());
//        userInfoVO.setUrl(activeUser.getUrls());
//        userInfoVO.setNickName(activeUser.getUser().getNickName());
//        List<String> roleNames = activeUser.getRoles().stream().map(Role::getRoleName).collect(Collectors.toList());
//        userInfoVO.setRoles(roleNames);
//        userInfoVO.setPerms(activeUser.getPermissions());
//        userInfoVO.setIsAdmin(activeUser.getUser().getType()==UserTypeEnum.SYSTEM_ADMIN.getTypeCode());
//        DepartmentVO dept = departmentService.edit(activeUser.getUser().getDeptId());
//        if(dept!=null){
//            userInfoVO.setDepartment(dept.getDeptName());
//        }
        return userInfoVO;
    }

    /**
     * 更新用户状态
     *
     * @param userId 用户编号
     * @param status 用户状态
     * @return
     */
    @Override
    public void updateUserStatus(Long userId, Integer status) throws SystemException {
        User dbUser = userMapper.selectByPrimaryKey(userId);
        if (dbUser == null) {
            throw new SystemException(SystemCodeEnum.PARAMETER_ERROR, "要更新状态的用户不存在");
        }
        ActiveUser activeUser = (ActiveUser) SecurityUtils.getSubject().getPrincipal();
//        if(dbUser.getUserId().equals(activeUser.getUser().getUserId())){
//            throw new SystemException(SystemCodeEnum.PARAMETER_ERROR,"无法改变当前用户状态");
//        }else {
        User t = new User();
        t.setUserId(userId);
        t.setStatus(status);
        userMapper.updateByPrimaryKeySelective(t);
//        }
    }

    /**
     * 更新多个用户状态
     *
     * @param map 多个用户编号，用户状态
     * @return
     */
    @Override
    public void updateUserStatusMore(Map<String, Object> map) throws SystemException {
        userMapper.updateUserStatusMore(map);
    }


    public List<User> findUsersList() {
        //获取当前登录用户对象
        ActiveUser activeUser = (ActiveUser) SecurityUtils.getSubject().getPrincipal();

//        List<Long> ids= DepUtils.getDepartmentAndChildrenIds(departmentMapper.selectAll(),activeUser.getUser().getDeptId());

        List<User> usersList = userMapper.selectUsers();


//        //移除非部门编号集合中的归属人的资源
//        usersList.removeIf(users ->!ids.contains(users.getDeptId()));
        return usersList;
    }

    @Override
    public List<User> findCreateUsersList() {
        //获取当前登录用户对象
        ActiveUser activeUser = (ActiveUser) SecurityUtils.getSubject().getPrincipal();

//        List<Long> ids= DepUtils.getDepartmentAndChildrenIds(departmentMapper.selectAll(),activeUser.getUser().getDeptId());

        List<User> usersList = userMapper.selectCreateUsers();

//
//        //移除非部门编号集合中的创建的资源
//        usersList.removeIf(users ->!ids.contains(users.getDeptId()));
        return usersList;
    }


    /**
     * 后台查询用户列表
     *
     * @param pageNum
     * @param pageSize
     * @param userVO
     * @return
     */
    @Override
    public PageVO<User> getUserList(Integer pageNum, Integer pageSize, UserVO userVO) {
        PageHelper.startPage(pageNum, pageSize);
        User user = new User();
        BeanUtils.copyProperties(userVO, user);
        //获得登录用户
        ActiveUser activeUser = (ActiveUser) SecurityUtils.getSubject().getPrincipal();
        if (activeUser.getEmployee().getType() == 0) {//判断是否为超级管理员
            user.setEmployeeId(null);
        } else {
            user.setEmployeeId(activeUser.getEmployee().getEmpId());
        }
        List<User> userList = userMapper.getUserByEmpId(user);
        PageInfo<User> info = new PageInfo<>(userList);
        return new PageVO<>(info.getTotal(), userList);
    }

    /*
    *
    @Override
    public List<DeptClient> findDeptTreeByDeptIdList(Long deptIdList) {
        DeptClient deptClientDb = new DeptClient();
        deptClientDb.setDeptId(deptIdList);
        DeptClient deptClient = deptClientMapper.selectOne(deptClientDb);
        List<DeptClient> deptClients = deptClientMapper.selectAll();
        return DepUtils.getDepartmentAndChildrenIds(deptClients, deptClient);
    }*/

    /**
     * 根据账号名得到该账号下的所有部门信息
     *
     * @return
     */
    @Override
    public List<DeptClient> getDeptId(String accountName) {
        //查询所有部门
        DeptClient deptClientDb = new DeptClient();
        deptClientDb.setDeptId(userMapper.getDeptId(accountName));
        return  DepUtils.getDepartmentAndChildrenIds(departmentMapper.selectAll(), departmentMapper.selectOne(deptClientDb));
    }

    /**
     * 得到前台所有的角色
     *
     * @return
     */
    @Override
    public List<String> getAccountName() {
        //获得登录用户
        ActiveUser activeUser = (ActiveUser) SecurityUtils.getSubject().getPrincipal();
        //判断是否为超级管理员
        if (activeUser.getEmployee().getType() == 0) {
            return userMapper.getAccountName(null);
        } else {
            return userMapper.getAccountName(activeUser.getEmployee().getEmpId());
        }
    }

    /**
     * 更新用户状态（冻结或解冻）
     *
     * @param userId 用户编号
     * @param status 用户状态
     * @return
     */
    @Override
    public int updateStatus(Long userId, Integer status) {
        return userMapper.updateUserStatus(userId, status);
    }

    /**
     * 根据用户id得到用户信息
     *
     * @param userId id
     * @return
     */
    @Override
    public User selectUserById(Long userId) {
        return userMapper.selectUserById(userId);
    }

    /**
     * 删除或批量删除（用户下线）
     *
     * @param userId id集合
     * @return
     */
    @Override
    public int deleteUserById(Long[] userId) {
        //删除用户的角色
        //userMapper.deleteRole(userId);
        return userMapper.deleteUserById(userId);
    }

    /**
     * 修改密码
     *
     * @param user 新密码
     * @throws SystemException
     */
    @Override
    public void updatePwd(User user) {
        User user1=userMapper.selectByPrimaryKey(user.getUserId());
        String pwd=MD5Utils.md5Encryption(user.getPassword(),user1.getSalt());
        userMapper.editPwd(user1.getUserId(),pwd);
    }
}
